package com.kc.web.controller.business;

import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.kc.business.domain.BizBusinessGoods;
import com.kc.business.domain.BizBusinessOrder;
import com.kc.business.domain.BizBusinessOrderGoods;
import com.kc.business.domain.BizScenicBusiness;
import com.kc.business.domain.dto.BizBusinessOrderGoodsDTO;
import com.kc.business.domain.dto.BizBusinessOrderInfoDTO;
import com.kc.business.domain.dto.BizOrderInfoDTO;
import com.kc.business.domain.dto.BizOrderStatusInfoDTO;
import com.kc.business.domain.query.BizBusinessOrderQuery;
import com.kc.business.domain.query.BizBusinessRefuseRefundQuery;
import com.kc.business.enums.businessOrder.BusinessOrderRefundStatusEnum;
import com.kc.business.enums.businessOrder.BusinessOrderStatusEnum;
import com.kc.business.mapper.BizGoodsOrderMapper;
import com.kc.business.service.IBizBusinessOrderService;
import com.kc.business.service.IBizScenicBusinessService;
import com.kc.common.core.controller.BaseController;
import com.kc.common.core.domain.AjaxResult;
import com.kc.common.core.domain.entity.SysDictData;
import com.kc.common.core.page.TableDataInfo;
import com.kc.common.utils.CommonUtils;
import com.kc.common.utils.RocketMQTemplate;
import com.kc.common.utils.StringUtils;
import com.kc.common.utils.WxPartnerService;
import com.kc.system.service.ISysDictDataService;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/business/businessOrder")
public class BizBusinessCenterOrderController extends BaseController {
    @Resource
    private IBizBusinessOrderService kcBusinessOrderService;
    @Resource
    private IBizScenicBusinessService bizScenicBusinessService;
    @Resource
    private ISysDictDataService dictDataService;
    @Resource
    private BizGoodsOrderMapper kcGoodsOrderMapper;
    @Resource
    private WxPartnerService wxPartnerService;
    @Resource
    private RocketMQTemplate rocketMQTemplate;

    /**
     * 商家中心-订单列表
     * @param businessId
     * @param status
     * @return
     */
    @PreAuthorize("@ss.hasPermi('business:businessOrder:getOrderList')")
    @GetMapping(value = "/getOrderList")
    public TableDataInfo getList(Integer businessId, Integer status) {
        BizScenicBusiness bizScenicBusiness = bizScenicBusinessService.getBusinessInfoById(businessId);
        startPage();
//        TableDataInfo tableDataInfo = getDataTable(kcBusinessOrderService.getOrderList(businessId,status));
//        tableDataInfo.setRows(kcBusinessOrderService.orderList(businessId,status,bizScenicBusiness));
        List<BizBusinessOrderInfoDTO> kcBusinessOrderInfoDTOList = new ArrayList<>();
        List<BizBusinessOrder> kcBusinessOrderList = kcBusinessOrderService.getOrderList(businessId,status);
        TableDataInfo tableDataInfo = getDataTable(kcBusinessOrderList);
        //获取商家信息
        kcBusinessOrderList.forEach(kcBusinessOrder -> {
            BizBusinessOrderInfoDTO kcBusinessOrderInfoDTO= new BizBusinessOrderInfoDTO();
            //订单下商品列表
            List<BizBusinessOrderGoods> kcBusinessOrderGoodsList = kcBusinessOrderService.getOrderGoodsList(kcBusinessOrder.getId());
            Integer goodsNum = 0;//订单下商品总数量
            List<BizBusinessOrderGoodsDTO> goodsList = new ArrayList<>();
            for(BizBusinessOrderGoods kcBusinessOrderGoods : kcBusinessOrderGoodsList){
                goodsNum += kcBusinessOrderGoods.getGoodsNum();
                BizBusinessOrderGoodsDTO bizBusinessOrderGoodsDTO = new BizBusinessOrderGoodsDTO(kcBusinessOrderGoods.getGoodsName(),kcBusinessOrderGoods.getGoodsPrice(),
                        kcBusinessOrderGoods.getGoodsNum(),kcBusinessOrderGoods.getGoodsImage(),kcBusinessOrderGoods.getGoodsIntro());
                BizBusinessGoods bizBusinessGoods = JSONObject.parseObject(kcBusinessOrderGoodsList.get(0).getGoodsData(),BizBusinessGoods.class);
                bizBusinessOrderGoodsDTO.setLables(StringUtils.split(bizBusinessGoods.getGoodsLable(),","));
                goodsList.add(bizBusinessOrderGoodsDTO);
            }
            kcBusinessOrderInfoDTO.setGoodsList(goodsList);
            Long days = CommonUtils.getDayDiff(kcBusinessOrderGoodsList.get(0).getUseStartTime(),kcBusinessOrderGoodsList.get(0).getUseEndTime());
            Long expireDate = 0l;//确认过期秒数
            if(kcBusinessOrder.getStatus() == 1){
                expireDate =  CommonUtils.getBetweenSecond(kcBusinessOrder.getPayDate(), kcBusinessOrder.getConfirmDate());
            }else if(kcBusinessOrder.getStatus() == 0){
                expireDate =  CommonUtils.getBetweenSecond(kcBusinessOrder.getCreateTime(), kcBusinessOrder.getConfirmDate());
            }
            String statusName = "";
            //订单信息处理
            if(bizScenicBusiness.getMainTypeId() == 1 && kcBusinessOrder.getStatus() == 3){
                statusName = dictDataService.selectDictLabel("business_restaurant_use_status",kcBusinessOrder.getStatus().toString());
            }
            BizOrderInfoDTO kcOrderInfoDTO = new BizOrderInfoDTO(kcBusinessOrder.getId(), kcBusinessOrder.getOrderSn(),
                    "", "",
                    kcBusinessOrderGoodsList.get(0).getUseUserNum(),
                    kcBusinessOrderGoodsList.get(0).getGoodsNum(), days, kcBusinessOrder.getCouponMoney(),
                    expireDate, kcBusinessOrder.getStatus(),
                    statusName,kcBusinessOrder.getRefundReason(),kcBusinessOrder.getRefundRemark());
            //(Integer orderId, String orderSn, String createTime, String useStartTime, String useEndTime,
            // Integer useUserNum, Integer goodsNum, Long days, String reservedName, String reservedMobile, Double couponMoney,
            // String couponId, Double payMoney, Double orderMoney, Long expireDate, Integer status, String statusName)
            String[] useArr = kcBusinessOrderService.getOrderUseDate(kcBusinessOrderGoodsList.get(0).getUseStartTime(),kcBusinessOrderGoodsList.get(0).getUseEndTime(),bizScenicBusiness,kcOrderInfoDTO);
            kcOrderInfoDTO.setUseStartTime(useArr[0]);
            kcOrderInfoDTO.setUseEndTime(useArr[1]);
            kcOrderInfoDTO.setStartWeek(useArr[2]);
            kcOrderInfoDTO.setEndWeek(useArr[3]);
            kcOrderInfoDTO.setGoodsNum(goodsNum);
            kcOrderInfoDTO.setOrderMoney(kcBusinessOrder.getOrderMoney());
            kcOrderInfoDTO.setPayMoney(kcBusinessOrder.getPayMoney());
            kcOrderInfoDTO.setReservedName(kcBusinessOrderGoodsList.get(0).getReservedName());
            kcOrderInfoDTO.setReservedMobile(kcBusinessOrderGoodsList.get(0).getReservedMobile());
            kcOrderInfoDTO.setCommentId(kcBusinessOrder.getCommentId());
            kcOrderInfoDTO.setRefundApplyDate(kcBusinessOrder.getRefundApplyDate());
            kcOrderInfoDTO.setCreateTime(kcBusinessOrder.getCreateTime());
            kcOrderInfoDTO.setRemark(kcBusinessOrder.getRemark());
            kcOrderInfoDTO.setRefundStatus(kcBusinessOrder.getRefundStatus());
            if(bizScenicBusiness.getMainTypeId().equals(2)) {
                BizBusinessGoods bizBusinessGoods = JSONObject.parseObject(kcBusinessOrderGoodsList.get(0).getGoodsData(),BizBusinessGoods.class);
                kcOrderInfoDTO.setLables(Arrays.asList(StringUtils.split(bizBusinessGoods.getGoodsLable(),",")));
            }
            if(!kcBusinessOrder.getCommentId().equals(0)){
                kcOrderInfoDTO.setCommentStatus(1);
            }
            if(kcBusinessOrder.getStatus() == 4){
                kcOrderInfoDTO.setRefundExpire(CommonUtils.getBetweenSecond(kcBusinessOrder.getRefundApplyDate(), kcBusinessOrder.getRefundConfirmDate()));
            }
            kcOrderInfoDTO.setStatusName(dictDataService.selectDictLabel("business_order_status",kcBusinessOrder.getStatus().toString()));
            kcBusinessOrderInfoDTO.setBizOrderInfoDTO(kcOrderInfoDTO);
//            if(kcBusinessOrder.getStatus() == 4){
//                kcBusinessOrderInfoDTO.setRefuseReason(dictDataService.selectDictLabel("business_order_refund_refuse_reason"));
//            }

            kcBusinessOrderInfoDTOList.add(kcBusinessOrderInfoDTO);

        });

        tableDataInfo.setRows(kcBusinessOrderInfoDTOList);
        return tableDataInfo;
    }

//    @PreAuthorize("@ss.hasPermi('business:businessOrder:getOrderStatusList')")
    @GetMapping(value = "/getOrderStatusList/{businessId}")
    public AjaxResult getOrderStatusList(@PathVariable("businessId") Integer businessId) {
        //餐饮business_restaurant_order_status  住宿 business_hotel_order_status   玩乐business_pleasure_order_status
        List<BizOrderStatusInfoDTO> kcOrderStatusInfoDTOList = new ArrayList<>();
        BizScenicBusiness kcScenicBusiness = bizScenicBusinessService.getBusinessInfoById(businessId);
        List<SysDictData> dictDataList = new ArrayList<>();
        SysDictData sysDictData = new SysDictData();
        if(kcScenicBusiness.getMainTypeId() == 1) {
            sysDictData.setDictType("business_restaurant_order_status");
            dictDataList = dictDataService.selectDictDataList(sysDictData);
        }else if(kcScenicBusiness.getMainTypeId() == 2){
            sysDictData.setDictType("business_hotel_order_status");
            dictDataList = dictDataService.selectDictDataList(sysDictData);
        }else{
            sysDictData.setDictType("business_order_status");
            dictDataList = dictDataService.selectDictDataList(sysDictData);
        }

        dictDataList.forEach(dictData -> {
            Integer status = Integer.parseInt(dictData.getDictValue());
            Integer num = 0;
//            if(kcScenicBusiness.getMainTypeId().equals(3)){
//                LambdaQueryWrapper<KcGoodsOrder> queryWrapper = new LambdaQueryWrapper<>();
//                if(!status.equals(9)){
//                    queryWrapper.eq(KcGoodsOrder::getStatus, status);
//                }
//                queryWrapper.eq(KcGoodsOrder::getMerchid, businessId);
//                queryWrapper.eq(KcGoodsOrder::getGoodsType, -4);
//                queryWrapper.eq(KcGoodsOrder::getIsDeleted, 0);
//                num = kcGoodsOrderMapper.selectCount(queryWrapper);
//
//            }else {
//                num = kcBusinessOrderService.getCountNum(businessId, status);
//            }
            //kcOrderStatusInfoDTOList.add(new BizOrderStatusInfoDTO("status",status,dictData.getDictLabel()+"("+num+")",num));
            if(status != -1) {
                kcOrderStatusInfoDTOList.add(new BizOrderStatusInfoDTO("status", status, dictData.getDictLabel(), num));
            }
        });
        if(kcScenicBusiness.getMainTypeId() == 2){
            kcOrderStatusInfoDTOList.add(new BizOrderStatusInfoDTO("status",4,"售后/退款",0));
        }
        return AjaxResult.success(kcOrderStatusInfoDTOList);
    }

    /**
     * 商家中心-订单退款审核
     * @param kcBusinessRefuseRefundQuery
     * @return
     */
    @PreAuthorize("@ss.hasPermi('business:businessOrder:refundCheck')")
    @PutMapping(value = "/refundCheck")
    public AjaxResult refundExamine(@Valid @RequestBody BizBusinessRefuseRefundQuery kcBusinessRefuseRefundQuery){

        if(kcBusinessRefuseRefundQuery.getRefundStatus() != -1 && kcBusinessRefuseRefundQuery.getRefundStatus() != 1){
            return AjaxResult.error("操作失败，请稍后重试");
        }
        BizBusinessOrder businessOrder = kcBusinessOrderService.getOrderInfo(kcBusinessRefuseRefundQuery.getOrderId(),0);
        if(!BusinessOrderStatusEnum.REFUNDING.getValue().equals(businessOrder.getStatus())){
            return AjaxResult.error("操作失败，请稍后重试");
        }
        if(BusinessOrderRefundStatusEnum.REFUSE.getValue().equals(kcBusinessRefuseRefundQuery.getRefundStatus())) {
            //拒绝退款
            if(kcBusinessRefuseRefundQuery.getRefuseReason() == null || kcBusinessRefuseRefundQuery.getRefuseReason().equals("")){
                return AjaxResult.error("操作失败，请稍后重试");
            }
            //订单状态变为退款之前状态
            businessOrder.setStatus(businessOrder.getRawStatus());
            businessOrder.setRawStatus(BusinessOrderStatusEnum.NOT_PAY.getValue());
            businessOrder.setRefuseReason(kcBusinessRefuseRefundQuery.getRefuseReason());
            businessOrder.setRefuseRemark(kcBusinessRefuseRefundQuery.getRefuseRemark());
            kcBusinessOrderService.updateOrder(businessOrder,businessOrder.getUserId());
        }else{
            //todo 通过需要退款,变更订单状态为退款中(先改状态后退款)
            businessOrder.setStatus(BusinessOrderStatusEnum.REFUNDING.getValue());
            businessOrder.setRefundStatus(kcBusinessRefuseRefundQuery.getRefundStatus());
            //执行微信退款
            kcBusinessOrderService.updateOrder(businessOrder,businessOrder.getUserId());
            //execRefund(kcBusinessOrder);
            //todo 执行退款操作，需要使用消息队列到APP端去退款
            rocketMQTemplate.sendDelayMessage("business_order_refund_auto_check",businessOrder,30);
        }
        return AjaxResult.success();
    }


    /**
     * 订单取消
     * @return
     */
    @PreAuthorize("@ss.hasPermi('business:businessOrder:orderCancel')")
    @PutMapping(value = "/orderCancel")
    public AjaxResult orderCancel(@Valid @RequestBody BizBusinessOrderQuery kcBusinessOrderQuery){
        BizBusinessOrder kcBusinessOrder = kcBusinessOrderService.getOrderInfo(kcBusinessOrderQuery.getOrderId(),0);
        if(BusinessOrderStatusEnum.NOT_PAY.getValue().equals(kcBusinessOrder.getStatus())){
            //未付款取消订单(直接取消)
            kcBusinessOrder.setStatus(BusinessOrderStatusEnum.CLOSED.getValue());
            kcBusinessOrderService.updateOrder(kcBusinessOrder,0);
        }else if(BusinessOrderStatusEnum.PAYED_WAITING_SEND.getValue().equals(kcBusinessOrder.getStatus())
        || BusinessOrderStatusEnum.WAITING_USE.getValue().equals(kcBusinessOrder.getStatus())){
            //待使用和待确认状态，需要退款
            kcBusinessOrder.setStatus(BusinessOrderStatusEnum.REFUNDING.getValue());
            kcBusinessOrderService.updateOrder(kcBusinessOrder,0);
            //todo 执行退款操作，需要使用消息队列到APP端去退款
            //execRefund(kcBusinessOrder);
            rocketMQTemplate.sendDelayMessage("business_order_auto_close",kcBusinessOrder,30);

        }else{
            return AjaxResult.error("操作失败，请稍后重试");
        }

        return AjaxResult.success();
    }

    /**
     * 订单确认
     * @return
     */
    @PreAuthorize("@ss.hasPermi('business:businessOrder:orderConfirm')")
    @PutMapping(value = "/orderConfirm")
    public AjaxResult orderConfirm(@Valid @RequestBody BizBusinessOrderQuery kcBusinessOrderQuery){
        BizBusinessOrder kcBusinessOrder = kcBusinessOrderService.getOrderInfo(kcBusinessOrderQuery.getOrderId(),0);
        if(BusinessOrderStatusEnum.PAYED_WAITING_SEND.getValue().equals(kcBusinessOrder.getStatus())){
            kcBusinessOrder.setStatus(BusinessOrderStatusEnum.WAITING_USE.getValue());
            kcBusinessOrderService.updateOrder(kcBusinessOrder,kcBusinessOrder.getUserId());
        }else{
            return AjaxResult.error("操作失败，请稍后重试");
        }
        return AjaxResult.success();
    }

    /**
     * 订单完成
     * @return
     */
    @PreAuthorize("@ss.hasPermi('business:businessOrder:orderFinish')")
    @PutMapping(value = "/orderFinish")
    public AjaxResult orderFinish(@Valid @RequestBody BizBusinessOrderQuery kcBusinessOrderQuery){
        BizScenicBusiness kcScenicBusiness = bizScenicBusinessService.getBusinessInfoById(kcBusinessOrderQuery.getBusinessId());
        BizBusinessOrder kcBusinessOrder = kcBusinessOrderService.getOrderInfo(kcBusinessOrderQuery.getOrderId(),0);
        if(BusinessOrderStatusEnum.USEING.getValue().equals(kcBusinessOrder.getStatus())){
            kcBusinessOrder.setStatus(BusinessOrderStatusEnum.COMPLETED.getValue());
            BizBusinessOrder businessOrder = new BizBusinessOrder();
            businessOrder.setId(kcBusinessOrder.getId());
            businessOrder.setStatus(BusinessOrderStatusEnum.COMPLETED.getValue());
            //kcBusinessOrderService.updateOrder(businessOrder,kcBusinessOrder.getUserId());

            //todo 企业转个人
            Map<String, Object> respMap = wxPartnerService.finishProfitsSharing(
                    kcScenicBusiness.getSubMchid(),
                    kcBusinessOrder.getTransactionId(),
                    kcBusinessOrder.getOrderSn(),
                    String.format("%s订单结算", "商家")
            );
            if (respMap != null) {
                if (HttpStatus.HTTP_OK == Integer.parseInt(String.valueOf(respMap.get("httpStatusCode")))) {
                    Map<String, Object> map = wxPartnerService.queryProfitSharingStatus(
                            kcScenicBusiness.getSubMchid(),
                            kcBusinessOrder.getTransactionId(),
                            kcBusinessOrder.getOrderSn());
                    List<Map<String, Object>> receivers = (List<Map<String, Object>>) map.get("receivers");
                    if (CollectionUtils.isNotEmpty(receivers)) {
                        Map<String, Object> receiverMap = receivers.get(0);
                        String receiverMchid = String.valueOf(receiverMap.get("receiver_mchid"));
                        if (kcScenicBusiness.getSubMchid().equals(receiverMchid)) {
                            BigDecimal actualReceiveAmount = new BigDecimal(String.valueOf(receiverMap.get("amount")));
                            kcBusinessOrder.setActualReceivedAmount(actualReceiveAmount);
                            kcBusinessOrderService.updateOrder(businessOrder,kcBusinessOrder.getUserId());
                        }
                    }
                }
            }

        }else{
            return AjaxResult.error("操作失败，请稍后重试");
        }
        return AjaxResult.success();
    }



}
